cbuffer PerFrame {
  uniform float4x4 WVP;
};

cbuffer WireFrame {
  uniform float2 WinScale;
  uniform float3 WireColor;
  uniform float4 FillColor;
};

struct VSInput {
  float4 Position0 : POSITION0; //Main vertex, w is used for vertex ID in the triangle
  float3 Position1 : POSITION1;
  float3 Position2 : POSITION2;
};

struct VSOutput {
  float4 PositionPS : SV_POSITION;
  noperspective float3 Distance : TEXCOORD0;
};

VSOutput VS_Wireframe(VSInput input) {
  VSOutput output;
  
  float4 pos = input.Position0;
  float w = pos.w;
  pos.w = 1.0;
  
  output.PositionPS = mul(pos, WVP);
  
  //Compute 2D position of current vertex
  float2 p0 = output.PositionPS.xy / output.PositionPS.w;
  
  //Project p1 and p2 and compute vectors v1 = p1 - p0 and v2 = p2 - p0
  float4 p1 = mul(float4(input.Position1, 1.0), WVP);
  float2 v1 = WinScale * ((p1.xy / p1.w) - p0);
  
  float4 p2 = mul(float4(input.Position2, 1.0), WVP);
  float2 v2 = WinScale * ((p2.xy / p2.w) - p0);
  
  //Compute 2D area of the triangle
  float area = abs(v1.x * v2.y - v1.y * v2.x);
  
  //Compute distance from vertex to line in 2D coords
  float h = area / length(v1-v2);
  
  //Determine which vertex we're dealing with
  if(w < 0.1) {
    output.Distance = float3(h, 0, 0);
  } else if(w < 1.1) {
    output.Distance = float3(0, h, 0);
  } else {
    output.Distance = float3(0, 0, h);
  }
  
  //Fix perspective correction
  //output.Distance *= output.PositionPS.w;
  
  return output;
}

float4 PS_Wireframe(VSOutput input) : SV_TARGET0 {
  //Undo perspective correction
  float3 dist = input.Distance ;//* input.PositionPS.w;
  
  float d = min(dist.x, min(dist.y, dist.z));
  
  float I = exp2(-2.0 * d * d);
  
  float4 color = I * float4(WireColor, 1.0) + (1.0 - I) * FillColor;
  
  return color;
}

technique10 {
  pass pass0 {
    SetGeometryShader(0);
		SetVertexShader(CompileShader(vs_4_0, VS_Wireframe()));
		SetPixelShader(CompileShader(ps_4_0, PS_Wireframe()));
  }
}